<?php

	// object : obj instantiator
	// accepts same arguments as obj constructor
	// see obj class
	function object($a=null){
		if(!is_scalar($a)) return new obj($a);
		$o = new obj;
		$o->set_list(func_get_args());
		return $o;
	}
	
	function smout(){
		return getObj('Smout');	
	}
	
	function smerr(){
		static $smerr;
		if(!$smerr) $smerr = new Smerr;
		return $smerr;	
	}
	
	function stdstream($n){
		switch($n){
			case 0:
				return smin();
			case 1:
				return smout();
			case 2:
				return smerr();
		}	
	}
	
	function sm_client_id(){
		static $smcid;
		if(!$smcid) $smcid = md5(
			$_SERVER['SERVER_NAME'] .
			$_SERVER['REMOTE_ADDR'] .
			$_SERVER['HTTP_USER_AGENT']
		);
		return $smcid;
	}
	
	function sm_set_error_handler($f){
		globset('error_handler', $f);
	}
	
	function call_error_handler(){
		$a = func_get_args();
		return call_user_func_array($GLOBALS['smuoi\error_handler'], $a);
	}
		
	function back_error($m='Error', $e=E_NOTICE, $b=0, $store=false){
		$a = array_pick($b+1, debug_backtrace());
		if($c = array_pick('class', $a)) $c .= array_pick('type', $a);
		if($f = array_pick('function', $a)) $f .= '()';
		if(!$store) call_error_handler($e, "$c$f $m", $a['file'], $a['line']);
		else return "$c$f $m in {$a['file']} on line {$a['line']}";
	}
	
	// String basics
	
	function sm_beginswith($hay, $n){
		return (substr($hay, 0, strlen($n)) == $n);	
	}
	
	function sm_endswith($hay, $n){
		return (substr($hay, strlen($n)*-1) == $n);	
	}
	
	function sm_hasparenthesis($s, $b, $e=null){
		return (sm_beginswith($s, $b) && sm_endswith($s, (!is_null($e) ? $e : $b)));
	}
	
	function sm_prefix($s, $g='/'){
		return ($p = strpos($s, $g)) ? substr($s, 0, $p) : '';	
	}
	
	function sm_suffix($s, $g='.'){
		return is_integer($p = strrpos($s, $g)) ? substr($s, $p+1) : '';	
	}
	
	function sm_strpos($hay, $n){
		return is_integer($i = strpos($hay, $n)) ? $i : -1;	
	}

	// GPC, GLOBALS & REQUEST HEADERS

	function get($k){
		if(isset($_GET[$k])) return $_GET[$k];
	}

	function post($k){
		if(isset($_POST[$k])) return $_POST[$k];
	}

	function cookie($k){
		if(isset($_COOKIE[$k])) return $_COOKIE[$k];
	}
	
	function globvar($k){
		if(isset($GLOBALS[$k])) return $GLOBALS[$k];
	}
	
	// get & cookie var shortcut
	function userglobal($k){
		if(isset($_GET[$k])) return $_GET[$k];
		if(isset($_COOKIE[$k])) return $_COOKIE[$k];
	}
	
	// $n must be lower case
	function req($n){
		static $rh;
		if(is_null($rh)) foreach(apache_request_headers() as $k=>$v) $rh[strtolower($k)] = $v;
		if(isset($rh[$n])) return $rh[$n];
	}
	
	if(!function_exists("apache_request_headers")){
		// If you run PHP as CGI you may not have this function. 
		// This version returns strtoupper keys while the real apache_request_headers returns header names as they were sent.
		// in either case use req($name) to find a single request header
		function apache_request_headers(){
			static $a;
			if(is_null($a)) foreach($_SERVER as $k=>$v) if(substr($k, 0, 5) == "HTTP_") $a[substr($k, 5)] = $v;
			return $a;
   		} 	
	}
	
	// alphanum permits underscores by default since it is used principally to create namespaces from classpaths.
	// set $x to false to omit, or use your own extra characters (escape as for perl regex) 
	function alphanum($v, $x='_'){
		return preg_replace("/[^A-Za-z0-9$x]/", '', $v);
	}
	
	// Fairly efficient, very hard to guess
	function rand_string($l=40, $s=''){
		while(($y = strlen($s)) < $l) $s .= base_convert(mt_rand($y, SMUOI_TIME_IN), 10, 32);
		if($n = ($y - $l)) $n = ($n - rand(0, $n));
		return substr($s, $n, $l);
	}
	
	function smuoi_orientation_constants(){
		static $a = array(
			'%{DOC_DIR}%'=>DOC_DIR,
			'%{DSK_DIR}%'=>DSK_DIR,
			'%{SMUOI_DIR}%'=>SMUOI_DIR
		);
		return $a;
	}
	
##	USEFUL
	
	function is_serialized($s) {
		return sjo::is_serialized($s);
	}
		
	function bytesize($n, $d=2){
		return Useful::bytesize($n, $d);
	}
	
	function is_valid_email($e){
		return Useful::is_valid_email($e);
	}
	
##	HostInterface
	
	function smuoi_filename($n, $x=false){
		return HostInterface::filename($n, $x);	
	}
	
	function smuoi_dirname($n){
		return HostInterface::dirname($n);	
	}
	
	function filename_increment($fp){
		return HostInterface::filename_increment($fp);
	}
	
	function smuoi_xtn($n, $h=false){
		return HostInterface::get_xtn($n, $h);
	}
		
	function writeToFile($f, $s, $m='w'){
		return HostInterface::writeToFile($f, $s, $m);	
	}
	
	function is_text_file($fp){
		return HostInterface::is_text_file($fp);
	}
	
	function is_ini_file($fp){
		return HostInterface::is_ini_file($fp);
	}
	
	if(!function_exists('parse_ini_string')){
		function parse_ini_string($s, $ps=false){
			return HostInterface::parse_ini_string($s, $ps);
		}
	}
	
##	SMERNEL

	// two identical shortcuts
	function sn(){
		return $GLOBALS['SMERNEL'];
	}
	
	function Smernel(){
		return $GLOBALS['SMERNEL'];
	}

	function getObj($o){
		return $GLOBALS['SMERNEL']->getObj($o);
	}
	
	// getDb() : alias of sn()->getDatabase
	function proxy($D=DOM_ID){
		return $GLOBALS['SMERNEL']->proxy($D);
	}
	
	function db(){
		return proxy();
	}
	
	function Package($name, $D=DOM_ID){
		if($dp = proxy($D)) return $dp->package($name);
	}
	
	function Fmgr(){
		return Package('Fmgr');
	}
	
	function nn(){
		return Package('nicename');
	}
	
	function smdb($id=false){
		return ($id) ? proxy('root')->get($id) : proxy('root');
	}
	
	function smroot(){
		return Package('SmRoot', 'root');
	}
	
	function Domain($D=DOM_ID){
		return $GLOBALS['SMERNEL']->domain($D);
	}
	
	function is_domain($D){
		return is_file(ETC_DIR."/conf/$D");	
	}
	
	function is_database($D){
		return is_file(ETC_DIR."/db/$D");
	}	
	
	function is_root(){
		if(PUBLIC_DOMAIN || (!$u = usr())) return false;	
		return $u->is_root();
	}
		
	function sm_whoami(){
		return (!$u = usr()) ? 'world' : $u->name;
	}
	
	function sm_amiroot($for_real=false){
		return (PUBLIC_DOMAIN || (!$u = usr())) ? false : ((!$for_real) ? $u->is_root() : ($u instanceof SmRoot_Root));
	}
	
	function usurp(){
		return (PUBLIC_DOMAIN && usr() && (get('smuoi_usurpas') != 'off'));	
	}
	
	function My(){
		return getObj('My');	
	}
	
	function Smurly($ß=null){
		if(is_null($ß)) return getObj('Smurly');
		return getObj('Smurly')->resolve(substr($ß, 1, -1));	
	}
	
	function is_smurly($ß){
		return preg_match('/^\{([a-zA-Z0-9_\.]+)\}$/', $ß);
	}
	
	function smopen($ñ){
		return smrf($ñ);
	}
	
	function sm_open($file){
		if(match_smrf($file)) return smrf($file);
		$cwd = sm_cwd();
		$fmgr = $cwd->pkg;
		$fp = path_resolve($cwd->realpath($file));
		if(!$fmrp = $fmgr->fp_fmrp($fp)) return false;
		return $fmgr->open($fmrp);
	}
	
	function sm_open_parent($file){
		$cwd = sm_cwd();
		$fmgr = $cwd->pkg;
		if(match_smrf($file)){
			if(!$fmrp = path_rewind($file)) return false;	
		}else{
			if(!$fp = path_rewind(path_resolve($cwd->realpath($file)))) return false;
			if(!$fmrp = $fmgr->fp_fmrp($fp)) return false;
		}
		return $fmgr->open($fmrp);
	}
	
	function path_resolve($p){
		$a = explode('/', $p, 2);
		$b = smuoi_explode('/', array_pop($a));
		foreach($b as $i=>$c){
			switch($c){
				case '.':
					array_splice($b, $i, 1);
					break;
				case '..';
					if(!$i) return NULL;
					array_splice($b, $i-1, 2);
			}
		}
		return array_shift($a).'/'.implode('/', $b);
	}
	
	function path_rewind($p, $n=1){
		$a = explode('/', $p, 2);
		$b = smuoi_explode('/', array_pop($a));
		if(count($b) < $n) return NULL;
		array_splice($b, -$n);
		return array_shift($a).'/'.implode('/', $b);
	}
	
	function sm_fopen($f, $m){
		if(!$file = sm_open($f)){
			if($m == 'r') return false;
			if(!$parent = sm_open_parent($f)) return false;
			if(!$file = $parent->mkfil($f)) return false;
		}
		if($m[0] == 'x') return false;
		if(!smuoi_is_file($file)) return false;
		return new Fileput($file, $m);
	}
	
	function stdport($n){
		return Transput();	
	}
	
	function smrf($smrf){
		list($dom, $sig, $path) = parse_smrf($smrf);
		if(!$proxy = proxy($dom)) return false;
		$a = explode('@', $sig);
		// no arroba ? it's an fmrp
		if(count($a) == 1) return $proxy->package('fmgr')->get("{$a[0]}:$path");
		// preceding arroba is id
		if($a[0]) $obj = $proxy->get($a[0]);
		// following it is package
		else $obj = $proxy->package($a[1]);
		return (!$obj) ? false : (!$path ? $obj : $obj->get($path));
	}
	
	function parse_smrf($smrf){
		if(!$m = match_smrf($smrf)) return array(DOM_ID, 'docs', $smrf);
		$path = substr($smrf, strlen($m[0]));
		$n = count($m = explode('::', $m[1]));
		$dom = ($n > 1) ? $m[0] : DOM_ID;
		$sig = ($n == 1) ? $m[0] : $m[1];
		return array($dom, $sig, $path);
	}
	
	function match_smrf($smrf){
		return preg_match('/^([^\/]+):/', $smrf, $m) ? $m : false;
	}
	
	function sm_realpath($fmrp){
		return Fmgr()->fmrp_fp($fmrp);
	}
	
	function sm_cwd(){
		return sn()->cwd();	
	}
	
	function sm_getcwd(){
		return sn()->getcwd();
	}
	
	function sm_chdir($D){
		return sn()->chdir($D);	
	}
	
	function sm_cwdom(){
		return sn()->cwdom();	
	}
	
	function sm_getcwdom(){
		return sn()->getcwdom();
	}
	
##	RESOURCE TESTING
		
	function smuoi_is_row($o){
		return ($o instanceof _smuoiDbRow);
	}
	
	function smuoi_is_user($o){
		return ($o instanceof SmRoot_User);
	}
	
	function smuoi_is_sudoer($o){
		return ($o instanceof SmRoot_Sudoer);
	}
	
	function smuoi_is_root($o){
		return ($o instanceof SmRoot_Root);
	}
	
	function smuoi_is_group($o){
		return ($o instanceof SmRoot_group);
	}
	
	function smuoi_is_domain($o){
		return ($o instanceof SmRoot_Domain);
	}
	
	function smuoi_is_rsrc($o){
		return ($o instanceof Smuoi_Resource);
	}
	
	function smuoi_is_dir($o){
		return ($o instanceof Fmgr_Directory);
	}
	
	function smuoi_is_file($o){
		return ($o instanceof Fmgr_File);
	}
	
	function smuoi_is_text($o){
		return ($o instanceof Fmgr_Text);
	}
	
	function smuoi_is_image($o){
		return ($o instanceof Fmgr_Image);
	}
	
	function smuoi_is_readable($o){
		return sm_test_and_call($o, 'is_readable');
	}
	
	function smuoi_is_writable($o){
		return sm_test_and_call($o, 'is_writable');
	}
	
	function smuoi_is_executable($o){
		return sm_test_and_call($o, 'is_executable');
	}
	
	function sm_test_and_call($o, $m){
		return (is_object($o) && (is_callable(array($o, $m)))) ? $o->$m() : null;
	}
	
	function error_logging($L=null){
		return smerr()->error_logging($L);	
	}
	
	function sm_error_handler(){
		$a = func_get_args();
		return call_user_func_array(array(smerr(), 'handle_error'), $a);
	}
	
	function odump(){
		$s = '';
		foreach(func_get_args() as $o) $s .= print_r($o, 1)."\n";
		return $s;
	}
	
	function dumptrace($max=10){
		$a = debug_backtrace();
		for($i=0; $i<$max; $i++){
			if($i == count($a)) break;
			unset($a[$i]['object']);
		}
		return odump($a);
	}
		

